//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <eltypes.h>
#include <_pubcrt.h>
#include <stdlib.h>

_ELASTOS_NAMESPACE_USING

#include "CConsoleFile.h"
#include "CConsoleIo.h"

#ifdef  __cplusplus
extern "C" {
#endif

static CConsoleIo s_CConsoleIo;
ECode InitCConsoleIo()
{
    return s_CConsoleIo.Init();
}

ECode UninitCConsoleIo()
{
    return s_CConsoleIo.Uninit();
}

ECode __cdecl _Console_Write_AString(AString as)
{
    return s_CConsoleIo.Write(as);
}

ECode __cdecl _Console_Write_WString(WString ws)
{
    if (ws.IsNull()) return E_INVALID_ARGUMENT;

    Int32 len = WcsToMbs(NULL, ws, 0);
    if (len == -1) return E_INVALID_ARGUMENT;

    len++;
    char *pas = (char *)_MALLOCA(len);
    if(!pas) return E_OUT_OF_MEMORY;

    Int32 retlen = WcsToMbs(pas, ws, len);
    if (retlen == -1) return E_INVALID_ARGUMENT;

    ECode ec = s_CConsoleIo.Write(pas);

    _FREEA(pas, len);

    return ec;
}

ECode __cdecl _Console_WriteLine_WString(WString ws)
{
      ECode ec = _Console_Write_WString(ws);
      if (FAILED(ec)) return ec;
      return _Console_Write_AString("\n");
}

ECode __cdecl _Console_WriteLine_AString(AString as)
{
      ECode ec = _Console_Write_AString(as);
      if (FAILED(ec)) return ec;
      return _Console_Write_AString("\n");
}

Int32 __cdecl _Console_Read() {
    return s_CConsoleIo.Read();
}

ECode __cdecl _Console_ReadLine_AString(AStringBuf *pasBuf) {
    return s_CConsoleIo.ReadLine(pasBuf);
}

ECode __cdecl _Console_ReadLine_WString(WStringBuf *pwsBuf) {
    if (pwsBuf == NULL) return E_INVALID_ARGUMENT;
    Int32 len = pwsBuf->GetCapacity();
    if (len == 0) return E_INVALID_ARGUMENT;

    char *pas = (char *)_MALLOCA(len * sizeof(WChar) + 1);

    AStringBuf asBuf(pas, (len * sizeof(WChar) + 1));

    ECode ec = _Console_ReadLine_AString(&asBuf);
    if (FAILED(ec)) {
        _FREEA(pas, (len * sizeof(WChar) + 1));
        return ec;
    }

    Int32 outsize = len;
    Int32 insize = asBuf.GetLength();

    Int32 retlen = _toWString(NULL, pwsBuf->GetPayload(), &outsize, pas, &insize);
    _FREEA(pas, (len * sizeof(WChar) + 1));
    if (retlen == -1) return E_INVALID_ARGUMENT;

    pwsBuf->SetLength(retlen);

    return NOERROR;
}

ECode __cdecl _Console_SetIo_WString(UInt32 fd, WString ws)
{
   return s_CConsoleIo.SetIo(fd, ws);
}

IAbsoluteIO* __cdecl _Console_GetIo_Interface(UInt32 fd)
{
   return s_CConsoleIo.GetIo(fd);
}

Boolean __cdecl _Is_Console(UInt32 fd)
{
   return s_CConsoleIo.IsConsole(fd);
}

#ifdef  __cplusplus
}
#endif
